/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.netbeans.modules.form.editors;

import java.util.ArrayList;
import java.util.StringTokenizer;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.openide.awt.Mnemonics;


/**
 * A custom editor for array of Strings.
 *
 * @author  Jiri Vagner
 */
public class StringArrayCustomEditor extends javax.swing.JPanel {
    private static String EMPTY_STRING = "";  // NOI18N
    private static String SPACER = " "; // NOI18N
    private static String LINE_SEP = "\n";  // NOI18N
    
    static final long serialVersionUID =-4347656479280614636L;
    private StringArrayCustomizable editor;

    /** Initializes the Form with customized label text */
    public StringArrayCustomEditor(StringArrayCustomizable sac,
            String labelContent) {
        this(sac);
        Mnemonics.setLocalizedText(label, labelContent);        
    }

    /** Initializes the Form */
    public StringArrayCustomEditor(StringArrayCustomizable sac) {
        initComponents ();

        editor = sac;
        String[] sourceArr = editor.getStringArray();
        StringBuilder textBuffer = new StringBuilder();
        if (sourceArr != null) {
            for (int i = 0; i < sourceArr.length; i++) {
                String actValue = sourceArr[i];
                boolean lastRow = (i == (sourceArr.length - 1));
                
                // convert default " " spacer into empty line
                if (actValue != null && actValue.trim().length() == 0) {
                    actValue = EMPTY_STRING;
                }
                textBuffer.append(actValue);
                
                // not last row, add line separator
                if (!lastRow) {
                    textBuffer.append(LINE_SEP);
                }
            }
        }
        textArea.setText(textBuffer.toString());
        
        textArea.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void insertUpdate(DocumentEvent e) {
                updateValue();
            }
            @Override
            public void removeUpdate(DocumentEvent e) {
                updateValue();
            }
            @Override
            public void changedUpdate(DocumentEvent e) {
                updateValue();
            }
        });
    };

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the FormEditor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        scrollPane = new javax.swing.JScrollPane();
        textArea = new javax.swing.JTextArea();
        label = new javax.swing.JLabel();

        textArea.setColumns(20);
        textArea.setRows(5);
        scrollPane.setViewportView(textArea);
        textArea.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(StringArrayCustomEditor.class, "StringArrayCustomEditor.textArea.AccessibleContext.accessibleName")); // NOI18N
        textArea.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(StringArrayCustomEditor.class, "StringArrayCustomEditor.textArea.AccessibleContext.accessibleDescription")); // NOI18N

        label.setLabelFor(textArea);
        org.openide.awt.Mnemonics.setLocalizedText(label, org.openide.util.NbBundle.getMessage(StringArrayCustomEditor.class, "StringArrayCustomEditor.label.text")); // NOI18N

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(label, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 386, Short.MAX_VALUE)
                    .addComponent(scrollPane, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 386, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(label, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 171, Short.MAX_VALUE)
                .addContainerGap())
        );

        label.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(StringArrayCustomEditor.class, "StringArrayCustomEditor.label.AccessibleContext.accessibleName")); // NOI18N
        label.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(StringArrayCustomEditor.class, "StringArrayCustomEditor.label.AccessibleContext.accessibleDescription")); // NOI18N
    }// </editor-fold>//GEN-END:initComponents


    public void updateValue () {
        String lastToken = EMPTY_STRING;
        ArrayList<String> list = new ArrayList<String>();
        String text = textArea.getText();
        
        // input ends with empty line > spacer added
        if (text.endsWith(LINE_SEP)) {
            text += SPACER;
        }
        
        // fill list from text area content
        // note: tokenizer returns separator as tokens, this setting doesn't
        //       ignore empty text lines at the end of text
        StringTokenizer st = new StringTokenizer(text, LINE_SEP, true);
        while (st.hasMoreTokens()) {
            String actToken = st.nextToken();
            
            if (!actToken.equals(LINE_SEP)) {
                list.add(actToken);
            } else {
                // line contains only new line char 
                // and previuos ends with new line char > spacer added
                if (lastToken.equals(LINE_SEP)) {
                    list.add(SPACER);
                }
            }
            lastToken = actToken;
        }
        
        editor.setStringArray(list.toArray(new String[0]));
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel label;
    private javax.swing.JScrollPane scrollPane;
    private javax.swing.JTextArea textArea;
    // End of variables declaration//GEN-END:variables

}
